package com.axxc.cloud.config;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import org.apache.commons.lang3.StringUtils;
import org.springframework.util.StreamUtils;

import com.alibaba.fastjson.JSONObject;

/**
 * post 请求以requestbody 传参数时进行校验的类走过滤器
 * 
 * @see {@link com.axxc.cloud.config.SelfDefinitionFileter }
 */
public class PostRequestBodyCheckWrapper extends HttpServletRequestWrapper {
	private byte[] requestBody;
	private Charset charSet;

	public PostRequestBodyCheckWrapper(HttpServletRequest request) {
		super(request);
		if ("post".equalsIgnoreCase(request.getMethod().toString())) {
			// 对post请求 body参数校验
			try {
				String requestBodyStr = getRequestPostStr(request);
				if (StringUtils.isNotBlank(requestBodyStr)) {
					JSONObject resultJson = JSONObject.parseObject(requestBodyStr);
					System.out.println("前" + resultJson);

					Object[] obj = resultJson.keySet().toArray();
					List<String> nameList = new ArrayList<>();
					for (Object o : obj) {
						String value = StringUtils.trimToNull(resultJson.get(o).toString());
						resultJson.put(o.toString(), value);
						nameList.add(o.toString());
					}
					// 接口签名验证处理
					String signature = sortToSignature(nameList, resultJson, request);
					System.err.println(signature);
					
					requestBody = resultJson.toString().getBytes(charSet);
				} else {
					requestBody = new byte[0];
				}
			} catch (Exception e) {

			}
		}
	}

	private String sortToSignature(List<String> nameList, JSONObject resultJson, HttpServletRequest request) {
		StringBuilder urlBuilder = new StringBuilder();
		nameList.add("token");
		nameList.add("timestamp");
		nameList.stream().sorted().forEach(name -> {
			if ("token".equals(name) || "timestamp".equals(name)) {
				if ("token".equals(name) && null == request.getHeader(name)) {
					// TODO 应该抛出一个异常
					return;
				}
				urlBuilder.append(name).append(request.getHeader(name));
			} else {
				urlBuilder.append(name).append(resultJson.get(name).toString());
			}
		});
		return urlBuilder.toString();
	}

	public String getRequestPostStr(HttpServletRequest request) throws IOException {
		String charSetStr = request.getCharacterEncoding();
		if (charSetStr == null) {
			charSetStr = "UTF-8";
		}
		charSet = Charset.forName(charSetStr);

		return StreamUtils.copyToString(request.getInputStream(), charSet);
	}

	/**
	 * 重写 getInputStream(),避免在controller拿不到数据
	 */
	@Override
	public ServletInputStream getInputStream() {
		if (requestBody == null) {
			requestBody = new byte[0];
		}

		final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody);

		return new ServletInputStream() {
			@Override
			public boolean isFinished() {
				return false;
			}

			@Override
			public boolean isReady() {
				return false;
			}

			@Override
			public void setReadListener(ReadListener readListener) {
			}

			@Override
			public int read() {
				return byteArrayInputStream.read();
			}
		};
	}

	/**
	 * 重写 getReader()
	 */
	@Override
	public BufferedReader getReader() {
		return new BufferedReader(new InputStreamReader(getInputStream()));
	}

}
